{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Getting Started"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "var userHomeDir = System.getProperty(\"user.home\");\n",
    "var localRespoUrl = \"file://\" + userHomeDir + \"/.m2/repository/\";\n",
    "var langchain4jVersion = \"1.0.1\";\n",
    "var langchain4jbeta = \"1.0.1-beta6\";\n",
    "var langgraph4jVersion = \"1.6-SNAPSHOT\";"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Remove installed package from Jupiter cache"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash \n",
    "rm -rf \\{userHomeDir}/Library/Jupyter/kernels/rapaio-jupyter-kernel/mima_cache/org/bsc/langgraph4j"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "add local maven repository and install required maven dependencies"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%dependency /add-repo local \\{localRespoUrl} release|never snapshot|always\n",
    "// %dependency /list-repos\n",
    "%dependency /add org.slf4j:slf4j-jdk14:2.0.9\n",
    "%dependency /add org.bsc.langgraph4j:langgraph4j-core:\\{langgraph4jVersion}\n",
    "%dependency /resolve"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Define the State\n",
    "\n",
    "Our state will hold a list of messages."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import org.bsc.langgraph4j.state.AgentState;\n",
    "import org.bsc.langgraph4j.state.Channels;\n",
    "import org.bsc.langgraph4j.state.Channel;\n",
    "\n",
    "import java.util.Collections;\n",
    "import java.util.List;\n",
    "import java.util.Map;\n",
    "import java.util.Optional;\n",
    "\n",
    "// Define the state for our graph\n",
    "class SimpleState extends AgentState {\n",
    "    public static final String MESSAGES_KEY = \"messages\";\n",
    "\n",
    "    // Define the schema for the state.\n",
    "    // MESSAGES_KEY will hold a list of strings, and new messages will be appended.\n",
    "    public static final Map<String, Channel<?>> SCHEMA = Map.of(\n",
    "            MESSAGES_KEY, Channels.appender(ArrayList::new)\n",
    "    );\n",
    "\n",
    "    public SimpleState(Map<String, Object> initData) {\n",
    "        super(initData);\n",
    "    }\n",
    "\n",
    "    public List<String> messages() {\n",
    "        return this.<List<String>>value(\"messages\")\n",
    "                .orElse( List.of() );\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Define the Nodes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "import org.bsc.langgraph4j.action.NodeAction;\n",
    "import java.util.Collections;\n",
    "import java.util.Map;\n",
    "\n",
    "// Node that adds a greeting\n",
    "class GreeterNode implements NodeAction<SimpleState> {\n",
    "    @Override\n",
    "    public Map<String, Object> apply(SimpleState state) {\n",
    "        System.out.println(\"GreeterNode executing. Current messages: \" + state.messages());\n",
    "        return Map.of(SimpleState.MESSAGES_KEY, \"Hello from GreeterNode!\");\n",
    "    }\n",
    "}\n",
    "\n",
    "// Node that adds a response\n",
    "class ResponderNode implements NodeAction<SimpleState> {\n",
    "    @Override\n",
    "    public Map<String, Object> apply(SimpleState state) {\n",
    "        System.out.println(\"ResponderNode executing. Current messages: \" + state.messages());\n",
    "        List<String> currentMessages = state.messages();\n",
    "        if (currentMessages.contains(\"Hello from GreeterNode!\")) {\n",
    "            return Map.of(SimpleState.MESSAGES_KEY, \"Acknowledged greeting!\");\n",
    "        }\n",
    "        return Map.of(SimpleState.MESSAGES_KEY, \"No greeting found.\");\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. Define and Compile the Graph"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "import org.bsc.langgraph4j.StateGraph;\n",
    "import org.bsc.langgraph4j.GraphStateException;\n",
    "import static org.bsc.langgraph4j.action.AsyncNodeAction.node_async;\n",
    "import static org.bsc.langgraph4j.StateGraph.START;\n",
    "import static org.bsc.langgraph4j.StateGraph.END;\n",
    "\n",
    "import java.util.List;\n",
    "import java.util.Map;\n",
    "\n",
    "public class SimpleGraphApp {\n",
    "    \n",
    "    public static void main(String[] args) throws GraphStateException {\n",
    "        // Initialize nodes\n",
    "        GreeterNode greeterNode = new GreeterNode();\n",
    "        ResponderNode responderNode = new ResponderNode();\n",
    "\n",
    "        // Define the graph structure\n",
    "       var stateGraph = new StateGraph<>(SimpleState.SCHEMA, initData -> new SimpleState(initData))\n",
    "            .addNode(\"greeter\", node_async(greeterNode))\n",
    "            .addNode(\"responder\", node_async(responderNode))\n",
    "            // Define edges\n",
    "            .addEdge(START, \"greeter\") // Start with the greeter node\n",
    "            .addEdge(\"greeter\", \"responder\")\n",
    "            .addEdge(\"responder\", END)   // End after the responder node\n",
    "             ;\n",
    "        // Compile the graph\n",
    "        var compiledGraph = stateGraph.compile();\n",
    "\n",
    "        // Run the graph\n",
    "        // The `stream` method returns an AsyncGenerator.\n",
    "        // For simplicity, we'll collect results. In a real app, you might process them as they arrive.\n",
    "        // Here, the final state after execution is the item of interest.\n",
    "        \n",
    "        for (var item : compiledGraph.stream( Map.of( SimpleState.MESSAGES_KEY, \"Let's, begin!\" ) ) ) {\n",
    "\n",
    "            System.out.println( item );\n",
    "        }\n",
    "\n",
    "    }\n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "GreeterNode executing. Current messages: [Let's, begin!]\n",
      "NodeOutput{node=__START__, state={messages=[Let's, begin!]}}\n",
      "ResponderNode executing. Current messages: [Let's, begin!, Hello from GreeterNode!]\n",
      "NodeOutput{node=greeter, state={messages=[Let's, begin!, Hello from GreeterNode!]}}\n",
      "NodeOutput{node=responder, state={messages=[Let's, begin!, Hello from GreeterNode!, Acknowledged greeting!]}}\n",
      "NodeOutput{node=__END__, state={messages=[Let's, begin!, Hello from GreeterNode!, Acknowledged greeting!]}}\n"
     ]
    }
   ],
   "source": [
    "SimpleGraphApp.main(new String[]{});"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Java (rjk 2.2.0)",
   "language": "java",
   "name": "rapaio-jupyter-kernel"
  },
  "language_info": {
   "codemirror_mode": "java",
   "file_extension": ".jshell",
   "mimetype": "text/x-java-source",
   "name": "java",
   "nbconvert_exporter": "script",
   "pygments_lexer": "java",
   "version": "22.0.2+9-70"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
